查看原文
其他

万丈高楼平地起——基于飞桨PaddleGAN与PaddleRS实现建筑物样本扩充工具

百度AI 2022-12-19


01

项目背景与意义


我国利用卫星遥感监测数据开展土地卫片执法检查的历史可追溯到本世纪初。自2000年起,国土资源部启动了该方向的试点工作。到2010年为止,已经实现全国2859个城市全覆盖。2019年起,自然资源部增加了建筑物变化图斑的提取,每季度下发到各级执法部门,督促进行整改查处。作为遥感土地监测的主要技术之一,长期以来,建筑物变化检测在生产、生活中扮演至关重要的角色。

传统的遥感建筑物变化检测主要通过手动或半自动的方式进行,人工成本高,效率较低。随着人工智能技术的不断成熟和新模型的不断涌现,以人工智能手段辅助建筑物变化检测已经成为主流应用趋势。然而,基于深度学习的建筑物变化检测模型在很大程度上依赖于经过标注的大型数据集,而由于建筑物变化样本的稀有性和稀疏性,收集包含建筑物变化的大规模双时态图像既费时又费力。

为了解决这一问题,有研究者使用生成对抗网络(Generative Adversarial Network,GAN)对建筑物变化检测数据集进行数据生成相关的技术研究,从数量[1]和多样性[2]上对数据集进行扩展,以支撑下游任务,并取得令人瞩目的效果提升。

本项目基于飞桨生成对抗网络开发套件 PaddleGAN 提供的 Pix2Pix 模型实现对建筑物变化检测数据集的扩充,利用飞桨高性能遥感影像处理开发套件 PaddleRS 提供的 RealSR、ESRGAN 与 LESRCNN 模型实现对生成遥感影像的超分辨率重建。

02

Pix2Pix 模型简介

数据处理与代码实现


 模型简介 

Pix2Pix[3]是 CGAN 的一个变体,能够实现从标签(labels)到图像的映射。在原文中,作者利用 CGAN 完成了从标签到街景图像、立面图像和遥感影像的图像重建任务,也实现了图像上色、边缘重建图像以及从黑夜到白天的风格迁移。

图1:Pix2Pix[3]模型在各场景下图像重建效果


Pix2Pix 网络由一个生成器 G(U-Net 结构)与一个判别器 D(用于分类的全卷积网络结构),其训练过程可分为两部分:

  • 将 Label(一般是图像熵较低的数据)输入生成器 G,输出重建后的图像 Image-fake。在 Image-fake 与 Image-Gt 间计算 L1 损失并优化,以缩小两幅图像间的逐像素差距。

  • 将 Image-fake 与 Label、Image-Gt 与 Label 分别组成图像对并输入判别器 D,判别器 D 输出 Image-fake 或 Image-Gt 为真实图像的概率。使用 Image-fake、Image-Gt、Label 以及判别器 D 的输出计算 GAN 损失并优化,使生成器 G 生成图像的分布逼近真实影像的分布。GAN 损失的公式为:


其中,x 是输入的网络的原始图像(Label),z是高斯噪声,G(x,z)是 Image-fake,y 是要生成的图像(Image-Gt)。

图2:Pix2Pix[3]网络的训练、预测过程


由于采用了 L1 损失,Pix2Pix 网络在图像细节的还原度上相比之前的算法有了极大的提高。然而,Pix2Pix 的训练机制对数据集有较高的要求,即数据集中必须有成对的标签和真实影像。

 数据处理 

明确了模型对数据集的要求,接下来是准备数据。

▎基础数据集

本项目的目的是对数据集进行数据扩充(data augmentation,即数据增强),希望训练数据集具有充足的数据体量、丰富的数据多样性、以及足够的空间分辨率。经过综合考虑,选定开源的 WHU Building Dataset/Satellite datasetⅡ(East Asia)作为建筑物生成任务的基础数据集。数据集包含三个文件夹:切片(crop)过的数据、建筑物的矢量文件、切片之前的完整正射影像,如下图:

图3:数据集内容展示


▎处理思路

[2]类似,本项目提取数据集中的建筑物,以每个建筑物作为一个实例(instance),用作增强数据集的素材。每一次将原始遥感影像中的一个建筑物实例抹除,即将建筑物区域内像素调整为(0,0,0),作为 x(输入图像)。接着,将原遥感影像作为 y(生成图像),构成一个样本对。重复此过程,直到处理完原始建筑物数据集中的所有影像。需要再次强调的是,本项目采取实例级别的数据增强思路,即由每个独立的建筑物均可生成一个样本对。

图4:建筑物实例级别擦除,构建训练样本


从代码层面来说,有两种具体的实现思路:

思路一:
  • 使用 GDAL 库读取矢量数据;
  • 遍历每条矢量数据,根据第 i 个建筑物 Bi 坐标提取其周围的遥感影像块(尺寸为512*512),将其采样为栅格图,得到 Gt;
  • 将 Gt 中目标建筑物 Bi 范围内像素值设置为(0,0,0)。

思路二:
  • 遍历切片后的二值化标注,使用 OpenCV 查找标注中的白色多边形;
  • 对多边形进行筛选,删除面积过小的区域或位于图像边界处的区域;
  • 以每一个多边形区域 Ci 作为一个实例,将与二值化标注对应的遥感影像 Image 作为 Gt,Ci 范围内像素设置为(0,0,0),得到 Label。

▎代码实现

考虑到计算开销,本项目采用思路二,即基于切片后的栅格数据进行处理。切片后的每个影像块空间尺寸为512*512像素。数据集中的部分样本展示如下图:

图5:数据集切片效果展示


实现关键代码如下:

def get_filePath_fileName_fileExt(fileUrl):
    """
    获取文件路径, 文件名, 后缀名
    :param fileUrl:
    :return:
    """

    filepath, tmpfilename = os.path.split(fileUrl)
    shotname, extension = os.path.splitext(tmpfilename)
    return filepath, shotname, extension


def gan_img(img_path, lab_path, save_dir, vis=False):
    lab = cv2.imread(lab_path, -1)
    img = cv2.imread(img_path, -1)
    contours, hierarchy = cv2.findContours(lab, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    for i in range(len(contours)):
        # 计算面积,太小的去掉
        area = cv2.contourArea(contours[i])
        if area < 200:
            continue

        # 接边的建筑物去掉,仅保留轮廓完整的建筑物
        if 0 in contours[i]:
            continue

        # 外接矩形框,没有方向角
        x, y, w, h = cv2.boundingRect(contours[i])

        # 可视化,调试用
        if vis == True:
            img_to_draw = img.copy()
            cv2.drawContours(img_to_draw, contours, i, (000), thickness=-1)
            cv2.rectangle(img_to_draw, (x, y), (x + w, y + h), (02550), 2)
            # cv2.rectangle(img_to_draw, (x - 5, y - 5), (x + w + 10, y + h + 10), (0, 255, 0), 2)
            cv2.imshow("img_to_draw", img_to_draw)
            cv2.waitKey(0)

        # 每一个对象绘制一张图
        os.makedirs(save_dir, exist_ok=True)

        img_to_save = img.copy()
        # (0, 0, 0)作为标记,需要生成建筑的部分
        cv2.drawContours(img_to_save, contours, i, (000), thickness=-1)
        # axis=0 按垂直方向,axis=1 按水平方向,左侧为目标图像,右侧为Label
        img_dataset = np.concatenate((img, img_to_save), axis=1)
        f, s, e = get_filePath_fileName_fileExt(img_path)

        os.makedirs(os.path.join(save_dir, "pairs"), exist_ok=True)
        cv2.imwrite(os.path.join(save_dir, "pairs", s + "_" + str(i) + ".jpg"), img_dataset)

        os.makedirs(os.path.join(save_dir, "img"), exist_ok=True)
        os.makedirs(os.path.join(save_dir, "lab"), exist_ok=True)


最终,从每一栋建筑物可以得到一组增强样本对。如下图所示,左侧为 Gt,右侧为 Image,Image 中的黑色图斑是要生成建筑物的区域。可将 Gt 和 Image 拼接为 facades 数据集格式(左边 A 图右边 B 图水平拼接成一张宽1024高512的图像,A 和 B 的定义在配置文件中需要明确,输入右图生成左图,因此是 B to A)。

 图6:PaddleGAN 套件训练 Pix2Pix 模型样本数据格式

 基于 PaddleGAN 的 Pix2Pix 网络训练与推理 

首先安利一波:飞桨生成对抗网络开发套件——PaddleGAN 为开发者提供经典及前沿的生成对抗网络高性能实现,并支撑开发者快速构建、训练及部署生成对抗网络,以供学术、娱乐及产业应用。

开发套件的一大优势是拿来即用,仅需修改配置文件中少量参数即可实现神经网络的训练。同时,AI Studio 可以提供算力支持,每天 16GB 显存的 A100 显卡可用16小时,满足绝大多数网络的训练要求。

▎模型训练

可以根据教程修改配置文件一键启动模型训练,配置文件中重要参数的详细解释可以参考 AI Studio 项目。运行以下命令行开始训练:

# 开始训练
!python -u PaddleGAN/tools/main.py --config-file work/pix2pix_buildings.yaml

# 中断后重新开始
# !python -u PaddleGAN/tools/main.py --config-file work/pix2pix_buildings.yaml --resume output_d
本项目(链接在文末)在 work/pix2pix_buildings.yaml 保存了独立的配置文件,对每一个字段进行说明,希望能给大家带来帮助。

▎模型推理

PaddleGAN 中,在 tool 文件夹下提供了 inference.py 文件,实现模型的推理,但其中实现 pix2pix 采用了 facades 数据集的结构,导致很多新手在使用模型推理时把数据拼接成 facades 格式后再推理,走了弯路。

其实想实现推理,关键点只有三个:
  • 定义模型;
  • 读取预训练权重;
  • 数据处理(transformer 中的方法与参数)。

实现关键代码如下:

from ppgan.models.generators import UnetGenerator
g_net = UnetGenerator(3, 3, 8, 64, 'batch', False) #注释:参数在配置文件中
weight_path = "./work/epoch_200_weight.pdparams"
state_dicts = load(weight_path)['netG']
state_dicts = load(weight_path)['netG'] #注释:权重文件中包含了G与D的参数,这里是关键
g_net.set_state_dict(state_dicts)
g_net.eval()
transform = T.Compose([
    T.Transpose(),
    T.Normalize([127.5, 127.5, 127.5], [127.5, 127.5, 127.5])
]) #注释:参数在配置文件中test部分


推理文件保存于项目./work/predict 预测.py 路径。运行该文件,实现模型推理:

# p2p推理一下
!cp ./work/predict预测.py PaddleGAN/
!python PaddleGAN/predict预测.py


得到结果如下:

图7:训练结果展示


结果保存在 pair_results 文件夹。

▎项目优化

经过前几步操作,我们已经完成了数据处理以及生成对抗模型的训练与推理。但在实验中,我发现采用上面的步骤得到的效果并不能达到预期。例如,在生成的图像中有绿色的房顶:


图8:异常结果展示


于是,我对项目重新进行了思考,认为效果不佳的原因有两方面:

  • 生成图像大部分与原图相同,L1 损失中包含大量冗余部分;
  • 网络真正需要生成的区域较小,损失难以聚焦在这部分,而这个目标小区域才是我们真正需要的。

基于以上分析,我们采取措施进行调优,对数据进行裁剪,缩小尺寸为256*256,从而让生成建筑物的区域作为图像的主要区域,效果如下:

图9:优化后的训练数据集


数据生成区域在全图中的面积占比从百分之一左右提升到了十分之一,使用优化后的数据集进行训练,得到效果如下:

图10:优化后的生成结果

平房的颜色基本正常,是红砖的颜色;结构正常,屋脊清晰可见。综上,经过数据裁剪处理后,算法的生成效果具有明显的提升。

 超分辨率增强 

pix2pixHD 模型是 pix2pix 的升级版,采用两个生成器 G1 与 G2。简单理解,由 G1 生成低分辨率图像输入 G2,从而得到一个更好的结果。本项目借鉴这个思路,使用飞桨高性能遥感影像处理开发套件 PaddleRS 提供的预训练的 RealSR 模型对生成的建筑物遥感影像进行超分辨率重建,以期望能提升影像的清晰度。

第二波安利:PaddleRS 是遥感科研院所、相关高校共同基于飞桨开发的遥感处理平台,支持遥感图像分类、目标检测、图像分割以及变化检测等常用遥感任务,能够帮助开发者更便捷地完成从训练到部署全流程遥感深度学习应用。

图11:PaddleRS 架构图


▎模型介绍

图12:DRN[4]模型架构


DRN[4]模型结构基于 U-net 结构,在每种特征尺度上各增加了一个输出对应不同分辨率的影像。

图13:DRN[4]模型双重回归训练架构


方法的主要创新是针对超分辨率重建任务的解空间过大和难以获得高清影像对这两个问题,提出了对偶回归策略。模型除了学习低分辨率(Low-Resolution,LR)到高分辨率(High-Resolution,HR)图像的映射外,还学习了额外的对偶回归映射,用于从超分辨率图像估计下采样内核并重建 LR 图像,从而形成一个能够提供额外监督的闭环。

▎推理实现

使用 work/Super_Resolution_pre.py 文件,运行超分辨率方法,将分辨率提升至2w*2h。代码如下:

# 进行图像超分处理
import os
import glob
import paddle
import numpy as np
from PIL import Image
from paddlers.models.ppgan.apps.drn_predictor import DRNPredictor
from paddlers.models.ppgan.apps.lesrcnn_predictor import LESRCNNPredictor
from paddlers.models.ppgan.apps.realsr_predictor import RealSRPredictor
# 输出预测结果的文件夹
output = r'./Super_Resolution_out'
# 待输入的低分辨率影像位置
input_dir = r"./gan_low_solution_sample"
# 设置GPU为推理设备
paddle.device.set_device("gpu:0")
# 实例化
DRNpredictor = DRNPredictor(output)
LESRpredictor = LESRCNNPredictor(output)
RealSRpredictor = RealSRPredictor(output)
# 生成文件列表
list_images = glob.glob(input_dir + "/*.**g")
#遍历文件列表,模型推理
for filename in list_images:
    DRNpredictor.run(filename) # 预测
    LESRpredictor.run(filename) 
    RealSRpredictor.run(filename) 

▎效果展示

图14:超分辨率效果展示


细节方面差挺多的,一看就知道生成的。但如果用于样本扩充是没问题的,毕竟总比直接贴图多样性好一些,可以看做一种神秘的复杂滤波。

像素即是正义!!!

本项目也到此结束,当然训练还要继续!

03

总结与展望


生成样本的真实性有待提高,需研究更快速、更清晰的数据扩展方法。后续需要验证数据增强能否为下游任务带来明显增益。

▼ 参考文献
1.张轶, et al., 一种面向地物变化检测的空间约束条件下生成对抗网络遥感影像样本扩充方法. 2020.
2.Chen, H., W. Li, and Z. Shi, Adversarial Instance Augmentation for Building Change Detection in Remote Sensing Images. IEEE Transactions on Geoscience and Remote Sensing, 2021. PP(99): p. 1-16.
3.Isola, P., et al., Image-to-Image Translation with Conditional Adversarial Networks. IEEE, 2016.
4.Guo, Y., et al., Closed-loop Matters: Dual Regression Networks for Single Image Super-Resolution. IEEE, 2020.

▼ 相关地址
  • 本项目地址:
https://aistudio.baidu.com/aistudio/projectdetail/3716885?contributionType=1&shared=1
  • WHU Building Dataset/Satellite dataset Ⅱ(East Asia)数据集下载链接:
https://aistudio.baidu.com/aistudio/datasetdetail/56356
  • 飞桨生成对抗网络开发套件 PaddleGAN github 地址:
https://github.com/PaddlePaddle/PaddleGAN
  • 飞桨高性能遥感影像处理开发套件 PaddleRS github 地址:
https://github.com/PaddlePaddle/PaddleRS

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存